package ${domain}.module.wsys.mgr;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.github.pagehelper.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import ${domain}.frame.auth.LocalData;
import ${domain}.frame.auth.Token;
import ${domain}.frame.base.ErrorType;
import ${domain}.frame.base.SortType;
import ${domain}.frame.utils.IDgenerator;
import ${domain}.frame.utils.MapperUtil;
import ${domain}.frame.utils.Message;
import ${domain}.frame.utils.ValidationUtil;
import ${domain}.module.wsys.ent.Res;
import ${domain}.module.wsys.ent.ResTree;
import ${domain}.module.wsys.mpr.ResMapper;
import ${domain}.module.wsys.req.ResCreateRequest;
import ${domain}.module.wsys.req.ResDeleteRequest;
import ${domain}.module.wsys.req.ResFindRequest;
import ${domain}.module.wsys.req.ResLoadRequest;
import ${domain}.module.wsys.req.ResTreeRequest;
import ${domain}.module.wsys.req.ResUpdateRequest;
import ${domain}.module.wsys.rsp.ResCreateResponse;
import ${domain}.module.wsys.rsp.ResDeleteResponse;
import ${domain}.module.wsys.rsp.ResFindResponse;
import ${domain}.module.wsys.rsp.ResLoadResponse;
import ${domain}.module.wsys.rsp.ResTreeResponse;
import ${domain}.module.wsys.rsp.ResUpdateResponse;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * RES - 资源
 *
 * @author wangbing
 * @version 0.0.1
 * @since 2017-01-01
 */
@Transactional
@Service
public class ResManagerImpl implements ResManager {

    @Autowired
    private ResMapper resMapper;

    /**
     * 插入
     *
     * @param request 请求对象
     * @param token   令牌
     * @return 响应
     */
    public ResCreateResponse create(ResCreateRequest request, Token token) {
        ResCreateResponse response = new ResCreateResponse();

        ValidationUtil.validate(request, response);
        if (response.hasError()) {
            return response;
        }

        ResFindRequest resFindRequest = new ResFindRequest();
        resFindRequest.setResCode(request.getResCode());
        ResFindResponse resFindResponse = this.find(resFindRequest, token);
        if (resFindResponse.hasError()) {
            response.addErrors(resFindResponse.getErrors());
            return response;
        } else if (resFindResponse.getResult().size() > 0) {
            response.addError(ErrorType.BUSINESS_ERROR, Message.INSERT_DUPLICATE);
            return response;
        }

        long id = IDgenerator.nextId();
        Res entity = MapperUtil.map(request, Res.class);
        entity.setId(id);

        long result = resMapper.insert(entity, token);
        if (1L != result) {
            response.addError(ErrorType.BUSINESS_ERROR, Message.CREATE_FAILURE);
            return response;
        }
        response.setId(id);

        return response;
    }

    /**
     * 逻辑删除
     *
     * @param request 请求对象
     * @param token   令牌
     * @return 响应
     */
    public ResDeleteResponse delete(ResDeleteRequest request, Token token) {
        ResDeleteResponse response = new ResDeleteResponse();

        ValidationUtil.validate(request, response);
        if (response.hasError()) {
            return response;
        }

        long result = resMapper.delete(request.getId(), token);
        if (1L != result) {
            response.addError(ErrorType.BUSINESS_ERROR, Message.DELETE_FAILURE);
            return response;
        }
        response.setResult(result);

        return response;
    }

    /**
     * 更新
     *
     * @param request 请求对象
     * @param token   令牌
     * @return 响应
     */
    public ResUpdateResponse update(ResUpdateRequest request, Token token) {
        ResUpdateResponse response = new ResUpdateResponse();

        ValidationUtil.validate(request, response);
        if (response.hasError()) {
            return response;
        }

        Res entity = resMapper.getById(request.getId(), token);
        if (entity == null) {
            response.addError(ErrorType.BUSINESS_ERROR, Message.GET_FAILURE);
            return response;
        }

        MapperUtil.map(request, entity);
        long result = resMapper.update(entity, token);
        if (1L != result) {
            response.addError(ErrorType.BUSINESS_ERROR, Message.UPDATE_FAILURE);
            return response;
        }
        response.setResult(result);

        return response;
    }

    /**
     * 查询
     *
     * @param request 请求对象
     * @param token   令牌
     * @return 响应
     */
    @Transactional(readOnly = true)
    public ResFindResponse find(ResFindRequest request, Token token) {
        ResFindResponse response = new ResFindResponse();

        ValidationUtil.validate(request, response);
        if (response.hasError()) {
            return response;
        }

        if (request.getPageSize() != 0) {
            PageHelper.startPage(request.getPageNumber(), request.getPageSize());
        }
        if (StringUtil.isNotEmpty(request.getSortKey())) {
            PageHelper.orderBy(request.getSortKey() + " " + request.getSortType());
        }
        PageInfo<Res> pageInfo = new PageInfo<>(resMapper.find(request, token));

        response.setResult(pageInfo.getList());
        response.setTotalCount(pageInfo.getTotal());

        return response;
    }

    @Override
    public ResLoadResponse load(ResLoadRequest request, Token token) {
        ResLoadResponse response = new ResLoadResponse();

        ValidationUtil.validate(request, response);
        if (response.hasError()) {
            return response;
        }

        if (request.getPageSize() != 0) {
            PageHelper.startPage(request.getPageNumber(), request.getPageSize());
        }
        if (StringUtil.isNotEmpty(request.getSortKey())) {
            PageHelper.orderBy(request.getSortKey() + " " + request.getSortType());
        }
        PageInfo<Res> pageInfo = new PageInfo<>(resMapper.load(request, token));

        response.setResult(pageInfo.getList());
        response.setTotalCount(pageInfo.getTotal());

        return response;
    }

    @Override
    public ResTreeResponse tree(ResTreeRequest request, Token token) {
        ResTreeResponse response = new ResTreeResponse();

        ValidationUtil.validate(request, response);
        if (response.hasError()) {
            return response;
        }

        ResFindRequest resourceFindRequest = new ResFindRequest();
        resourceFindRequest.setPageSize(0);
        resourceFindRequest.setValid(true);
        resourceFindRequest.setSortKey("RES_CODE");
        resourceFindRequest.setSortType(SortType.ASC);
        ResFindResponse resourceFindResponse = this.find(resourceFindRequest, token);

        if (resourceFindResponse.hasError()) {
            response.addErrors(resourceFindResponse.getErrors());
            return response;
        }

        List<ResTree> data = new ArrayList<>();
        Map<String, ResTree> allMap = new HashMap<>();
        List<Res> result = resourceFindResponse.getResult();
        while (result.size() > 0) {
            Iterator<Res> iterator = result.iterator();
            while (iterator.hasNext()) {
                Res next = iterator.next();
                ResTree tree = new ResTree();
                tree.setId(next.getId());
                tree.setResCode(next.getResCode());
                tree.setResName(next.getResName());
                tree.setResType(next.getResType());
                tree.setResValue(next.getResValue());
                tree.setFree(next.getFree());
                tree.setValid(next.getValid());
                tree.setRowVersion(next.getRowVersion());
                tree.setLabel(next.getResName());

                allMap.put(tree.getResCode(), tree);
                iterator.remove();
                //尝试获取上级资源
                String code = next.getResCode();
                ResTree Ptree = null;
                while (code.length() > 0) {
                    code = code.substring(0, code.length() - 1);
                    Ptree = allMap.get(code);
                    if (Ptree != null) break;
                }
                if (Ptree != null) {
                    Ptree.addChild(tree);
                } else {
                    data.add(tree);
                }
            }
        }

        response.setResult(data);
        return response;
    }

    /**
     * 确保存在资源
     *
     * @param res   资源
     * @param token 令牌
     */
    @Override
    public void saveRes(String res, Token token) {
        ResFindRequest resFindRequest = new ResFindRequest();
        resFindRequest.setPageSize(0);
        resFindRequest.setResValueLike(res);
        ResManager resManager = LocalData.getBean(ResManager.class);
        ResFindResponse resFindResponse = resManager.find(resFindRequest, token);

        if (resFindResponse.getResult().size() == 0) {//资源不存在，主动收集资源
            ResCreateRequest resCreateRequest = new ResCreateRequest();
            resCreateRequest.setResCode(IDgenerator.nextUUID());
            resCreateRequest.setResName("默认");
            resCreateRequest.setResValue(res);
            resCreateRequest.setFree(false);
            resCreateRequest.setValid(true);
            resCreateRequest.setResType("WEB");
            resManager.create(resCreateRequest, token);
        }
    }
}
